package com.ishow.bs.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.web.filter.OncePerRequestFilter;

/**
 * 登录过滤
 */
public class SessionFilter extends OncePerRequestFilter {
	private static Logger log = Logger.getLogger(SessionFilter.class);

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.springframework.web.filter.OncePerRequestFilter#doFilterInternal(
	 * javax.servlet.http.HttpServletRequest,
	 * javax.servlet.http.HttpServletResponse, javax.servlet.FilterChain)
	 */
	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");// 解决页面乱码

		// 不过滤的uri
		String[] notFilter = new String[] { "index.do", "login.do" };
		// 请求的uri
		String uri = request.getRequestURI();
		log.debug("[session过滤器]过滤的URI：" + uri);
		// 是否过滤
		boolean doFilter = false;
		for (String s : notFilter) {
			if ("/".equals(uri)) {
				// 如果用户访问的根目录，则直接跳过
				doFilter = false;
				log.debug("[session过滤器]过滤器跳过拦截，用户访问根目录。URL:" + uri);
				break;
			}
			if (uri.indexOf(s) != -1) {
				// 如果uri中包含不过滤的uri，则不进行过滤
				doFilter = false;
				log.debug("[session过滤器]过滤器跳过拦截，白名单url。URL:" + uri);
				break;
			}
		}
		if (doFilter) {
			boolean sessionObj = request.getSession().getAttribute("isLogin") == null ? false
					: Boolean.valueOf(request.getSession().getAttribute("isLogin").toString());
			if (sessionObj != true) {
				log.debug("[session过滤器]过滤器拦截成功，登录session为null，URL:" + uri);
				// 登录超时
				if (isAjaxRequest(request)) {
					response.setHeader("sessionstatus", "timeout");// 在响应头设置session状态
					// response.getWriter().write()//用这个方法输出，会导致ajax请求收到数据后，执行error事件。而print方法则不会
					// response.getWriter().print(MessageCode.LOGIN_TIME_OUT);//
					// 其实这里输出随便什么内容都可以，主要的原因是，页面中的easyui的datagrid控件，虽然是用的ajax发的请求，但是如果不输出内容，会导致页面不执行全局的ajaxComplete方法，从而无法跳转到登录页
					return;
				} else {
					String mess = "<script type=\"text/javascript\">alert('登录超时，请重新登录。');window.location.replace('login.do');</script>";
					response.getWriter().print(mess);
					return;
				}
			} else {
				log.debug("[session过滤器]过滤器验证通过，登录session正常。URL:" + uri);
				// 如果session中存在登录者实体，则继续
				filterChain.doFilter(request, response);
			}
		} else {
			// 如果不执行过滤，则继续
			filterChain.doFilter(request, response);
		}
	}

	/**
	 * 判断是否是ajax提交过来的消息
	 * 
	 * @param request
	 * @return
	 */
	private boolean isAjaxRequest(HttpServletRequest request) {
		if (request.getHeader("x-requested-with") != null
				&& request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {
			// 如果是ajax请求响应头会有，x-requested-with；
			return true;
		}
		return false;
	}

}
